<div id="app"></div>
<script>
  let activeEffect = null;
  class Dep {
    subscribers = new Set();

    depend() {
      if (activeEffect) {
        this.subscribers.add(activeEffect);
      }
    }
    notify() {
      this.subscribers.forEach((effect) => effect());
    }
  }
  function watchEffect(effect) {
    activeEffect = effect;
    effect();
    activeEffect = null;
  }

  function searchDep(target, key) {
    let depsMap = targetMap.get(target);
    if (!depsMap) {
      targetMap.set(target, (depsMap = new Map()));
    }
    let dep = depsMap.get(key);
    if (!dep) {
      depsMap.set(key, (dep = new Dep()));
    }
    return dep;
  }

  let targetMap = new WeakMap();
  function reactive(raw) {
    return new Proxy(raw, {
      get(target, key, receiver) {
        let dep = searchDep(target, key);
        dep.depend();
        return Reflect.get(target, key, receiver);
      },
      set(target, key, value, receiver) {
        let dep = searchDep(target, key);
        let res = Reflect.set(target, key, value, receiver);
        dep.notify();
        return res;
      },
    });
  }

  let state = reactive({
    count: 0,
  });

  watchEffect(() => {
    console.log(state.count, "watchEffect");
  });
  state.count++;
</script>
